var express = require('express')
var router = express.Router()
const Role = require('../models/role')
const User = require('../models/user')
const sequelize = require('sequelize')
const Op = require('sequelize').Op
const Tool = require('../libs/tool')
const { check, validationResult } = require('express-validator/check')
const Interceptor = require('../libs/interceptor')
const config = require('../config/config')

/* GET roles listing. */
router.get('/', async function(req, res, next) {
  let whereObj = {}
  if (req.query.roleName) {
    whereObj['role_name'] = {
      [Op.like]: '%' + req.query.roleName + '%'
    }
  }
  let orderObj = []
  if (req.query.order && req.query.sortby) {
    orderObj.push([req.query.sortby, req.query.order])
  }
  let interceptor = new Interceptor(req)
  let { offset = 1, limit = 10 } = interceptor.page()
  let result = await Role.findAndCountAll({
    raw: true,
    where: whereObj,
    order: orderObj,
    offset: offset,
    limit: limit
  })
  for (let idata = 0; idata < result.rows.length; idata++) {
    let permissions = result.rows[idata]['permission'].split(',')
    let permissionNameArr = []
    permissions.forEach(key => {
      let name = ''
      config.features.some(feature => {
        if (feature.key === key) {
          name = feature.name
          return true
        }
      })
      if (name) {
        permissionNameArr.push(name)
      }
    })
    result.rows[idata].permissionNameArr = permissionNameArr
  }
  return res.json({
    code: 0,
    msg: '',
    items: result.rows,
    total: result.count
  })
})

router.get('/menus', async function(req, res, next) {
  let roles = await Role.findAll({
    raw: true
  })
  return res.json({
    code: 0,
    msg: '',
    features: config.features
  })
})

let dbValidator = [
  check('roleName')
    .not()
    .isEmpty()
    .withMessage('角色名不能为空'),
  check('permission')
    .not()
    .isEmpty()
    .withMessage('用户权限定义不能为空')
]
let createValidator = Object.assign([], dbValidator)
router.post('/', createValidator, async function(req, res) {
  const { permission } = req.body
  const errors = validationResult(req)
  if (!errors.isEmpty()) {
    let errObj = Tool.validatorError(errors)
    return res.status(errObj.code).json(errObj)
  }
  try {
    let role = await Role.create({
      roleName: req.body.roleName,
      permission: req.body.permission
    })
    return res.json({
      code: 0,
      msg: '',
      role: role
    })
  } catch (err) {
    let exceptionObj = Tool.exceptionError(err)
    return res.status(exceptionObj.code).json(exceptionObj)
  }
})

let updateValidator = Object.assign([], dbValidator)
updateValidator.push(
  check('roleId')
    .not()
    .isEmpty()
    .withMessage('角色ID不能为空')
)
router.put('/:roleId', updateValidator, async function(req, res) {
  const errors = validationResult(req)
  if (!errors.isEmpty()) {
    let errObj = Tool.validatorError(errors)
    return res.status(errObj.code).json(errObj)
  }
  let role = await Role.findByPk(req.params.roleId)
  if (!role) {
    return res.status(404).json({
      code: 404,
      msg: '未找到该数据'
    })
  }
  try {
    let updateData = {
      roleName: req.body.roleName,
      permission: req.body.permission
    }
    let affectedRows = await Role.update(updateData, {
      where: {
        roleId: req.params.roleId
      }
    })
    return res.json({
      code: 0,
      msg: '',
      affectedRows: affectedRows[0]
    })
  } catch (err) {
    let exceptionObj = Tool.exceptionError(err)
    return res.status(exceptionObj.code).json(exceptionObj)
  }
})

let deleteValidator = [
  check('roleIds')
    .not()
    .isEmpty()
    .withMessage('角色ID不能为空')
]
router.delete('/:roleIds', deleteValidator, async function(req, res) {
  const errors = validationResult(req)
  if (!errors.isEmpty()) {
    let errObj = Tool.validatorError(errors)
    return res.status(errObj.code).json(errObj)
  }
  let roleIds = req.params.roleIds.split(',')
  let roles = await Role.findAndCountAll({
    where: {
      roleId: {
        [Op.in]: roleIds
      }
    }
  })
  if (roles.count !== roleIds.length) {
    return res.status(404).json({
      code: 404,
      msg: '未找到匹配的数据'
    })
  }
  let inUse = await User.findAndCountAll({
    raw: true,
    attributes: [[sequelize.fn('COUNT', sequelize.col('*')), 'res_count']],
    where: {
      roleId: {
        [Op.in]: roleIds
      }
    }
  })
  if (inUse.count > 0 && inUse.rows[0]['res_count'] > 0) {
    return res.status(500).json({
      code: 500,
      msg: '角色被其它数据使用'
    })
  }
  try {
    let destroyedRows = await Role.destroy({
      where: {
        roleId: {
          [Op.in]: roleIds
        }
      }
    })
    return res.json({
      code: 0,
      msg: '',
      destroyedRows: destroyedRows
    })
  } catch (err) {
    let exceptionObj = Tool.exceptionError(err)
    return res.status(exceptionObj.code).json(exceptionObj)
  }
})

module.exports = router
